02.05 - Manejo de memoria
Lenguajes Estructurados
¿Qué es el manejo de memoria?
El manejo de memoria es la forma en que un programa puede solicitar y liberar memoria dinámicamente. Nos permite, entre otras cosas, crear estructuras de datos dinámicas.
¿Cómo se solicita memoria?
Para solicitar memoria, utilizamos la función malloc
.
int *p = malloc(sizeof(int));
¿Cómo se accede a la memoria?
Para acceder a la memoria, utilizamos el operador de indirección *
.
*p = 5;
¿Cómo se libera memoria?
Para liberar memoria, utilizamos la función free
.
free(p);
Función malloc()
La función malloc() en C se utiliza para asignar dinámicamente un bloque de memoria en tiempo de ejecución. El bloque de memoria que se asigna puede ser utilizado para almacenar datos de cualquier tipo, como números, caracteres, estructuras, matrices y otros objetos.
La función malloc() toma un único argumento, el tamaño en bytes que se desea asignar al bloque de memoria. Devuelve un puntero al inicio del bloque de memoria asignado, o NULL si la asignación de memoria falla.
A continuación, se presenta un ejemplo básico del uso de malloc():
#include <stdio.h>
#include <stdlib.h>
int main() {
int* p;
p = (int*)malloc(5 * sizeof(int)); // asigna un bloque de memoria para 5 enteros
if (p == NULL) {
printf("No se pudo asignar memoria");
return 1;
}
// se puede utilizar el bloque de memoria para almacenar datos
p[0] = 10;
p[1] = 20;
p[2] = 30;
p[3] = 40;
p[4] = 50;
// se debe liberar la memoria asignada con malloc() cuando ya no se necesita
free(p);
return 0;
}
En este ejemplo, malloc() se utiliza para asignar memoria para 5 enteros, y se comprueba si la asignación de memoria ha sido exitosa. Si es así, se utiliza el bloque de memoria asignado para almacenar algunos datos y, finalmente, se libera la memoria asignada con free().
Es importante tener en cuenta que la función malloc() no inicializa los datos en el bloque de memoria asignado, por lo que el programador debe inicializar explícitamente cualquier dato que se almacene en el bloque de memoria.
Además, si se utiliza malloc(), es necesario asegurarse de que la memoria asignada se libere adecuadamente con free() cuando ya no se necesite, para evitar fugas de memoria.
La función calloc()
La función calloc() también se utiliza para asignar memoria dinámicamente en tiempo de ejecución, pero difiere de malloc() en la forma en que inicializa el bloque de memoria asignado.
calloc()
inicializa el bloque de memoria asignado a ceros, mientras que malloc() no inicializa el bloque de memoria asignado.
La función calloc() toma dos argumentos:
- el número de elementos que se desean asignar
- el tamaño de cada elemento en bytes.
Devuelve un puntero al inicio del bloque de memoria asignado, o NULL si la asignación de memoria falla.
A continuación, se presenta un ejemplo básico del uso de calloc():
#include <stdio.h>
#include <stdlib.h>
int main() {
int* p;
// asigna un bloque de memoria para 5 enteros, inicializado a cero
p = (int*)calloc(5, sizeof(int));
if (p == NULL) {
printf("No se pudo asignar memoria");
return 1;
}
// se puede utilizar el bloque de memoria para almacenar datos
p[0] = 10;
p[1] = 20;
p[2] = 30;
p[3] = 40;
p[4] = 50;
// se debe liberar la memoria asignada con calloc() cuando ya no se necesita
free(p);
return 0;
}
Es importante tener en cuenta que la función calloc() puede ser más lenta que la función malloc(), ya que debe inicializar el bloque de memoria asignado a ceros.
Además, como en el caso de malloc(), es necesario asegurarse de que la memoria asignada con calloc() se libere adecuadamente con free() cuando ya no se necesite, para evitar fugas de memoria.
¿Cómo se puede redimensionar un bloque de memoria?
La función realloc() en C se utiliza para cambiar el tamaño de un bloque de memoria que ha sido asignado previamente con malloc(), calloc(), o realloc().
La función toma dos argumentos:
- un puntero al bloque de memoria que se desea cambiar de tamaño
- el nuevo tamaño en bytes que se desea asignar al bloque.
La función devuelve un puntero al bloque de memoria recién asignado, que puede ser el mismo puntero que el que se pasó como argumento o uno diferente.
La función realloc() puede ser útil en situaciones en las que se necesita más espacio en el bloque de memoria de lo que se asignó originalmente.
En lugar de liberar la memoria y luego volver a asignarla con un tamaño más grande, realloc() puede utilizarse para cambiar el tamaño del bloque existente de forma más eficiente.
Es importante tener en cuenta que la función realloc() puede fallar si no hay suficiente espacio contiguo disponible en la memoria para satisfacer la nueva asignación de tamaño. En ese caso, la función devuelve NULL y no se hace ningún cambio en el bloque de memoria original.
¿Cómo se puede copiar la memoria de una estructura?
Para copiar la memoria de una estructura, utilizamos la función memcpy
.
memcpy(libro2, libro1, sizeof(struct Libro));
¿Cómo se puede comparar la memoria de dos estructuras?
Para comparar la memoria de dos estructuras, utilizamos la función memcmp
.
if (memcmp(libro1, libro2, sizeof(struct Libro)) == 0) {
printf("Los libros son iguales\n");
}
¿Cómo se puede limpiar la memoria de una estructura?
Para limpiar la memoria de una estructura, utilizamos la función memset
.
memset(libro1, 0, sizeof(struct Libro));